ACPI: workaround for S3 fail in two facs tables case
authorKeir Fraser <keir.fraser@citrix.com>
Thu, 25 Feb 2010 20:56:43 +0000 (20:56 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Thu, 25 Feb 2010 20:56:43 +0000 (20:56 +0000)
Some legacy BIOS which support ACPI2.0+ may expose two FACS tables via
both FADT->FIRMWARE_CTRL and FADT->X_FIRMWARE_CTRL, but only lookup S3
waking_vector in the first one.

Signed-off-by: Wei Gang <gang.wei@intel.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
xen/arch/x86/acpi/boot.c

index 8e67cde539fee2e1b9c123b23cdf0cd824f2e75d..5a1dda0ee6d8ad38f6a5410824ba3c37f5692dec 100644 (file)
@@ -365,10 +365,15 @@ acpi_fadt_parse_sleep_info(struct acpi_table_fadt *fadt)
               acpi_sinfo.pm1b_evt_blk.address);
 
        /* Now FACS... */
-       if (fadt->header.revision >= FADT2_REVISION_ID)
-               facs_pa = fadt->Xfacs;
-       else
+       facs_pa = ((fadt->header.revision >= FADT2_REVISION_ID)
+                  ? fadt->Xfacs : (uint64_t)fadt->facs);
+       if (fadt->facs && ((uint64_t)fadt->facs != facs_pa)) {
+               printk(KERN_WARNING PREFIX
+                      "32/64X FACS address mismatch in FADT - "
+                      "%08x/%016"PRIx64", using 32",
+                      fadt->facs, facs_pa);
                facs_pa = (uint64_t)fadt->facs;
+       }
 
        facs = (struct acpi_table_facs *)
                __acpi_map_table(facs_pa, sizeof(struct acpi_table_facs));